/**
  ******************************************************************************
  * File Name          : loralink.c
  * Description        : This file provides code for the configuration
  *                      of the lora e22-400t22s instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
#include "lora.h"
#include "bsp.h"
#include "edct.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* lora queue define */
QueueHandle_t        LoRaRecv_qhd = NULL;
static StaticQueue_t lorarecv_stru;
static uint8_t       lorarecv_area[ LORARECV_QUE_LENGTH * LORARECV_QUE_ITEMSIZE ];

/* lora task */
TaskHandle_t xLoRaRecv_Thd = NULL;
StaticTask_t xLoRaRecv_Tcb;
StackType_t  xLoRaRecv_Stk[ LORARECV_STACK_SIZE ];

LoRa_BufType  LoRa_RecvBuf;
LoRa_BufType  LoRa_RecvIsr;

static uint16_t lora_netid;
static uint8_t  lora_localid;
static uint8_t  lora_channel;

volatile uint8_t LoRa_ConnectFlag = 0;

uint8_t LoRa_Init(void)
{
	LoRa_BspInit();
	
	LoRaRecv_qhd = xQueueCreateStatic(LORARECV_QUE_LENGTH,
	                                  LORARECV_QUE_ITEMSIZE,
	                                  lorarecv_area,
	                                  &lorarecv_stru);
	
	if(LoRa_StartUp() == 0)
	{
		printf("LoRa: Start success.\r\n");
	}
	else
	{
		printf("LoRa: Start fail!\r\n");
	}
	
	lora_localid = SW_Read();
  
	LoRa_DIDtoChannel(Edct_RunPara.did, &lora_netid, &lora_channel);
	
	_printf("LoRa Local ID: %d\r\n", lora_localid);
	_printf("LoRa Net ID  : %d\r\n", lora_netid);
	_printf("LoRa Channel : %d\r\n", lora_channel);
	
	if(LoRa_Config(lora_netid, lora_localid, lora_channel) == 0)
	{
		printf("LoRa: Config success.\r\n");
	}
	else
	{
		printf("LoRa: Config fail!\r\n");
	}
	
	vTaskDelay(100);
	
	return 0;
}

uint8_t LoRa_LinkSend(uint16_t dstid, const uint8_t *payload, uint8_t pllen)
{
	uint16_t netid;
	uint8_t sendbuf[20];
	
	if(pllen > 15)
  {
    return 1;
  }
	
	/* 此地址为目标地址 */
	netid = ((lora_netid << 4)& 0xfff0u) + dstid;
	
	sendbuf[0] = (uint8_t)(netid >> 8);
	sendbuf[1] = (uint8_t)netid;
	
	sendbuf[2] = lora_channel;
	
	sendbuf[3] = lora_localid;  /* 本机地址 */
	
	sendbuf[4] = pllen;
	
	memcpy(sendbuf+5, payload, pllen);
	
	LoRa_UartSendBuf(sendbuf, pllen + 5);
	
	return 0;
}


void vLoRaReceive_Task( void * pvParameters )
{
	LoRa_Init();
	
	while(1)
	{
		/* waiting for reply */
		if(xQueueReceive(LoRaRecv_qhd, &LoRa_RecvBuf, portMAX_DELAY) == pdTRUE)
		{
			if(LoRa_RecvBuf.buf[1] == (LoRa_RecvBuf.count-2))
			{
				if(LoRa_ReceiveDeal(LoRa_RecvBuf.buf[0], LoRa_RecvBuf.buf+2, LoRa_RecvBuf.buf[1]) == 0)
        {
          LoRa_ConnectFlag = 1;
          continue;
        }
			}
		}
    
    LoRa_ConnectFlag = 0;
	}
}

uint8_t LoRa_DIDtoChannel(const char *did, uint16_t *netid, uint8_t *channel)
{
	Route_DidFormatType format;
	
	if(Route_ParseDID(did, &format) != 0)
	{
		return 1;
	}
	
	*netid = (format.sequence / 120)+1;
	
	format.sequence = (format.sequence % 120);
	
	if((format.sequence & 0x01)!=0)
	{
		format.sequence = 64 - ((format.sequence/2)+1);
	}
	else
	{
		format.sequence = 64 + ((format.sequence/2)+1);
	}
	
	if(format.sequence == 18)
	{
		format.sequence = 125;
	}
	
	if(format.sequence == 50)
	{
		format.sequence = 3;
	}
	
	if(format.sequence == 82)
	{
		format.sequence = 126;
	}
	
	if(format.sequence == 114)
	{
		format.sequence = 2;
	}
	
	if(format.sequence > 127)
	{
		return 6;
	}
	
	*channel = format.sequence;

	return 0;
}
